/**
 * 
 */
package edu.umd.clip.lm.model.training;

import java.io.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import edu.umd.clip.lm.model.HistoryTreePayload;
import edu.umd.clip.lm.model.data.TrainingDataNodeReader;
import edu.umd.clip.lm.model.data.TrainingDataNodeWriter;
import edu.umd.clip.lm.util.tree.BinaryTree;

/**
 * @author  Denis Filimonov <den@cs.umd.edu>
 */
public class TrainingContext {
	private int iteration;
	/**
	 * 
	 */
	private BinaryTree<HistoryTreePayload> tree;
	/**
	 * 
	 */
	private ActiveNodeStorage<ActiveTreeNode>.ActiveNodeCollection activeNodes;
	/**
	 * 
	 */
	private Map<Integer, BinaryTree<HistoryTreePayload>> leaves;
	/**
	 * 
	 */
	private TrainingDataNodeReader dataReader;
	/**
	 * 
	 */
	
	private TrainingDataNodeWriter dataWriter;
	
	private File filename;
	
	private RandomAccessFile file;
	
	private AtomicInteger lastNodeId;

	/**
	 * 
	 */
	public TrainingContext(int iteration, int size, BinaryTree<HistoryTreePayload> tree, ActiveNodeStorage<ActiveTreeNode>.ActiveNodeCollection activeNodes) {
		this.iteration = iteration;
		this.tree = tree;
		this.activeNodes = activeNodes;
		this.leaves = new ConcurrentHashMap<Integer, BinaryTree<HistoryTreePayload>>(size);
		this.lastNodeId = new AtomicInteger(0);
	}

	/**
	 * @return the tree
	 */
	public BinaryTree<HistoryTreePayload> getTree() {
		return tree;
	}

	/**
	 * @param tree the tree to set
	 */
	public void setTree(BinaryTree<HistoryTreePayload> tree) {
		this.tree = tree;
	}

	/**
	 * @return the activeNodes
	 */
	public ActiveNodeStorage<ActiveTreeNode>.ActiveNodeCollection getActiveNodes() {
		return activeNodes;
	}

	/**
	 * @param activeNodes the activeNodes to set
	 */
	public void setActiveNodes(ActiveNodeStorage<ActiveTreeNode>.ActiveNodeCollection activeNodes) {
		this.activeNodes = activeNodes;
	}

	/**
	 * @return the currentLeaves
	 */
	public BinaryTree<HistoryTreePayload> getLeaf(Integer id) {
		return leaves.get(id);
	}

	/**
	 * @param currentLeaves the currentLeaves to set
	 */
	public void putLeaf(Integer id, BinaryTree<HistoryTreePayload> leaf) {
		this.leaves.put(id, leaf);
	}

	/**
	 * @return the lastNodeId
	 */
	public AtomicInteger getLastNodeId() {
		return lastNodeId;
	}

	/**
	 * @param lastNodeId the lastNodeId to set
	 */
	public void setLastNodeId(AtomicInteger nodeCount) {
		this.lastNodeId = nodeCount;
	}

	public TrainingDataNodeReader getDataReader() {
		return dataReader;
	}

	public void setDataReader(TrainingDataNodeReader dataReader) {
		this.dataReader = dataReader;
	}
	public TrainingDataNodeWriter getDataWriter() {
		return dataWriter;
	}
	public void setDataWriter(TrainingDataNodeWriter dataWriter) {
		this.dataWriter = dataWriter;
	}
	protected int getIteration() {
		return iteration;
	}

	protected File getFilename() {
		return filename;
	}

	protected void setFilename(File file) {
		this.filename = file;
	}

	protected RandomAccessFile getFile() {
		return file;
	}

	protected void setFile(RandomAccessFile file) {
		this.file = file;
	}
	
	public int getNodeCount() {
		return leaves.size();
	}
	
	public int getNextNodeId() {
		return lastNodeId.incrementAndGet();
	}
}